package com.lu.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lu.mapper.SysBrandMapper;
import com.lu.mapper.SysMerchantMapper;
import com.lu.mapper.SysStoreMapper;
import com.lu.model.entity.SysBrand;
import com.lu.model.entity.SysMerchant;
import com.lu.model.entity.SysStore;
import com.lu.model.enums.YesOrNoEnum;
import com.lu.model.exception.LuBootAssert;
import com.lu.model.request.BrandQueryRequest;
import com.lu.service.SysBrandService;
import com.lu.utils.SecurityUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 品牌 服务实现类
 * </p>
 *
 * @author currentCodeAuthor
 * @since 2022-07-31
 */
@RequiredArgsConstructor
@Service
public class SysBrandServiceImpl extends ServiceImpl<SysBrandMapper, SysBrand> implements SysBrandService {

  private final SysMerchantMapper merchantMapper;
  private final SysStoreMapper storeMapper;

  @Override
  public Page<SysBrand> pageList(BrandQueryRequest request) {
    QueryWrapper<SysBrand> brandQueryWrapper = new QueryWrapper<>();
    if(ObjectUtil.isNotEmpty(request.getStatus())){
      brandQueryWrapper.eq("status", request.getStatus());
    }
    if(ObjectUtil.isNotEmpty(request.getName())){
      brandQueryWrapper.like("name", request.getName());
    }
    brandQueryWrapper.orderByDesc("create_time");
    Page<SysBrand> brandPage = this.baseMapper.selectPage(new Page<>(request.getPageIndex(), request.getPageSize()), brandQueryWrapper);
    List<Long> brandIs = brandPage.getRecords().stream().map(SysBrand::getId).collect(Collectors.toList());
    //计算商户数量
    if(ObjectUtil.isEmpty(brandIs)){
      return brandPage;
    }
    QueryWrapper<SysMerchant> merchantQueryWrapper = new QueryWrapper<>();
    merchantQueryWrapper.select("id", "brand_id");
    merchantQueryWrapper.in("brand_id", brandIs);
    List<SysMerchant> merchants = merchantMapper.selectList(merchantQueryWrapper);
    Map<Long, List<SysMerchant>> merchantMap = merchants.stream().collect(Collectors.groupingBy(SysMerchant::getBrandId));
    //计算门店数量
    QueryWrapper<SysStore> storeQueryWrapper = new QueryWrapper<>();
    storeQueryWrapper.select("id", "relation_id");
    storeQueryWrapper.eq("business_mode", SysStore.BusinessMode.ELECTRONIC_COUPON.getMode());
    storeQueryWrapper.isNotNull("relation_id");
    storeQueryWrapper.in("relation_id", brandIs);
    List<SysStore> storesByBrand = storeMapper.selectList(storeQueryWrapper);
    Map<Long, List<SysStore>> storesByBrandMap = storesByBrand.stream().collect(Collectors.groupingBy(SysStore::getRelationId));
    Map<Long, List<SysStore>> storesByMerchantMap = new HashMap<>();
    if(ObjectUtil.isNotEmpty(merchants)){
      storeQueryWrapper = new QueryWrapper<>();
      storeQueryWrapper.select("id", "relation_id");
      storeQueryWrapper.eq("business_mode", SysStore.BusinessMode.OFFLINE.getMode());
      storeQueryWrapper.isNotNull("relation_id");
      storeQueryWrapper.in("relation_id", merchants.stream().map(SysMerchant::getId).collect(Collectors.toList()));
      List<SysStore> storesByMerchant = storeMapper.selectList(storeQueryWrapper);
      storesByMerchantMap = storesByMerchant.stream().collect(Collectors.groupingBy(SysStore::getRelationId));
    }
    for (SysBrand brand : brandPage.getRecords()) {
      List<SysMerchant> merchantList = merchantMap.get(brand.getId());
      List<SysStore> storeByBrandList = storesByBrandMap.get(brand.getId());
      //品牌下的商户
      brand.setMerchantCount(ObjectUtil.isEmpty(merchantList) ? 0 : merchantList.size());
      //品牌下的电子券门店
      brand.setStoreCount(ObjectUtil.isEmpty(storeByBrandList) ? 0 : storeByBrandList.size());
      if(ObjectUtil.isEmpty(merchantList)){
        continue;
      }
      for (SysMerchant merchant : merchantList) {
        //品牌下的商户的线下门店
        List<SysStore> storeByMerchantList = storesByMerchantMap.get(merchant.getId());
        if(ObjectUtil.isNotEmpty(storeByMerchantList)){
          brand.setStoreCount(brand.getStoreCount() + storeByMerchantList.size());
        }
      }

    }
    return brandPage;
  }

  @Override
  public List<SysBrand> brandList(BrandQueryRequest request) {
    QueryWrapper<SysBrand> brandQueryWrapper = new QueryWrapper<>();
    if(ObjectUtil.isNotEmpty(request.getStatus())){
      brandQueryWrapper.eq("status", request.getStatus());
    }
    if(ObjectUtil.isNotEmpty(request.getName())){
      brandQueryWrapper.like("name", request.getName());
    }
    brandQueryWrapper.orderByDesc("create_time");
    return this.baseMapper.selectList(brandQueryWrapper);
  }

  @Override
  public Long addBrand(SysBrand brand) {
    LuBootAssert.isTrue(ObjectUtil.isNotEmpty(brand.getName()), "请输入名称");
    LuBootAssert.isTrue(ObjectUtil.isEmpty(brand.getStatus())
        || Arrays.stream(YesOrNoEnum.values()).anyMatch(o -> o.getValue() == brand.getStatus()), "无效的状态参数");
    this.checkNameUnique(null, brand.getName());
    brand.setCreateUserId(SecurityUtil.getCurrentUser().getId());
    brand.setUpdateUserId(SecurityUtil.getCurrentUser().getId());
    this.baseMapper.insert(brand);
    return brand.getId();
  }

  @Override
  public SysBrand updateBrand(SysBrand brand) {
    LuBootAssert.isTrue(ObjectUtil.isNotEmpty(brand.getId()), "修改失败");
    LuBootAssert.isTrue(ObjectUtil.isEmpty(brand.getStatus())
        || Arrays.stream(YesOrNoEnum.values()).anyMatch(o -> o.getValue() == brand.getStatus()), "无效的状态参数");
    this.checkNameUnique(brand.getId(), brand.getName());
    brand.setUpdateUserId(SecurityUtil.getCurrentUser().getId());
    brand.setUpdateTime(LocalDateTime.now());
    this.baseMapper.updateById(brand);
    return this.baseMapper.selectById(brand.getId());
  }


  private void checkNameUnique(Long id, String name){
    if(ObjectUtil.isEmpty(name)){
      return;
    }
    QueryWrapper<SysBrand> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("name", name);
    if(ObjectUtil.isNotEmpty(id)){
      queryWrapper.ne("id", id);
    }
    Integer count = this.baseMapper.selectCount(queryWrapper);
    LuBootAssert.isTrue(count == 0, "名称不能重复");
  }

}
